package com.sugon.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.sugon.consts.BaseConsts;
import com.sugon.consts.ErmsCodePrefix;
import com.sugon.consts.FactoryTypeEnum;
import com.sugon.dao.SparePartDao;
import com.sugon.entity.*;
import com.sugon.modules.base.consts.SysApproveStatusConst;
import com.sugon.service.*;
import com.sugon.utils.Constant;
import com.sugon.utils.ProcessInfoEnum;
import com.sugon.utils.Query;
import com.sugon.utils.ShiroUtils;
import com.sugon.utils.excel.ExcelImport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.sugon.utils.ShiroUtils.getUserId;

/**
 * 备件清单Service实现类
 *
 * @author sugon
 * @date 2019-07-17 09:37:19
 */
@Service("sparePartService")
public class SparePartServiceImpl implements SparePartService {

    @Autowired
    private SparePartDao sparePartDao;
    @Autowired
    private FactoryTypeService factoryTypeService;
    @Autowired
    private DevTypeService devTypeService;
    @Autowired
    private SysConfigService configService;
    @Autowired
    private SysProcessInfoService processInfoService;
    @Autowired
    private SysDeptService deptService;

    @Override
    public boolean checkExists(String name, String spec) {
        Map<String, Object> param = new HashMap<>(2);
        param.put("name", name);
        param.put("spec", spec);
        return sparePartDao.queryExistsCount(param) > 0;
    }

    @Override
    public SparePartEntity queryObject(String id) {
        SparePartEntity sparePart = sparePartDao.queryObject(id);
        // 如果不需要展示真实安全库存，则修改下
        if (configService.getIsRealSafetyStock() == 0) {
            sparePart.setSafeNum(sparePart.getStockNum());
        }
        return sparePart;
    }

    @Override
    public List<SparePartEntity> queryList(Map<String, Object> map) {
        // 设置是否展示真安全库存 2021-04-12 09:51    by YuXD
        map.put("isRealSafetyStock", configService.getIsRealSafetyStock());
        //pe技术员,质量管理室人员 查询所有
        return sparePartDao.queryList(map);
    }

    @Override
    public int queryTotal(Map<String, Object> map) {
        return sparePartDao.queryTotal(map);
    }

    @Override
    public int save(SparePartEntity sparePart) {
        String id = RandomUtil.randomString(32);
        sparePart.setId(id);
        sparePart.setPartCode(generateUniqueCode());
        if (StrUtil.isEmpty(sparePart.getCreateUser())) {
            sparePart.setCreateUser(getUserId());
        }
        sparePart.setCreateDate(DateUtil.date());
        //未审批状态
        if (sparePart.getStatus() == null) {
            sparePart.setStatus(SysApproveStatusConst.NOT_YET_APPROVE);
        }
        sparePart.setInitNum(0);
        sparePart.setStockNum(sparePart.getInitNum());
        sparePart.setScrapNum(0);
        sparePart.setTransitNum(0);
        sparePart.setDelFlag(Constant.IS_NOT_DEL_INT);
        // 设置录入单位
        String workshop = ShiroUtils.getWorkshop();
        if (StrUtil.isNotEmpty(workshop)) {
            SysDeptEntity dept = deptService.queryObject(workshop);
            if (dept != null) {
                sparePart.setUseUnit(dept.getName());
            }
        }
        // 检查是否设置图片，如果没有则设置默认图片
        if (StrUtil.isEmpty(sparePart.getReserve2())) {
            // 设置默认图片
            sparePart.setReserve2(BaseConsts.SP_DEFAULT_IMAGE_URL);
        }
        // 备件规格录入时，对首尾的空格进行自动去除，中间的空格最多只有两个
        String spec = sparePart.getSpec();
        if (StrUtil.isNotEmpty(spec)) {
            sparePart.setSpec(handleSpec(spec));
        }
        int rows = sparePartDao.save(sparePart);
        if (rows > 0) {
            // 添加审批消息
            processInfoService.startProcess(ProcessInfoEnum.SPA_BJGL, sparePart.getId(), "提交备件信息");
        }
        return rows;
    }

    /**
     * 处理备件规格字符串
     * 首尾的空格进行自动去除，中间的空格最多只有两个
     *
     * @param sparePartSpec 备件规格
     * @return
     */
    private String handleSpec(String sparePartSpec) {
        if (StrUtil.isEmpty(sparePartSpec)) {
            return sparePartSpec;
        }
        // 去除首位
        sparePartSpec = StrUtil.trim(sparePartSpec, 0);
        // 中间有三个或以上空格的全部处理成两个空格
        return ReUtil.replaceAll(sparePartSpec, "\\s{3,}|\t", "  ");
    }

    @Override
    public synchronized String generateUniqueCode(Object object) {
        String spareUniqueCode = (String) object;
        if (StrUtil.isEmpty(spareUniqueCode)) {
            // 获取DB中最新记录
            spareUniqueCode = sparePartDao.getLastestPartCode();
        }
        // 生成新的唯一编码
        spareUniqueCode = com.sugon.modules.utils.StrUtil.increase(spareUniqueCode, ErmsCodePrefix.SPARE_PART_CODE_PREFIX, 6, 1);
        // 确保最新生成备件编码不重复
        SparePartEntity sparePart = queryByCode(spareUniqueCode);
        if (sparePart == null) {
            return spareUniqueCode;
        }
        return generateUniqueCode(spareUniqueCode);
    }

    @Override
    public int update(SparePartEntity sparePart) {
        sparePart.setUpdateUser(getUserId());
        sparePart.setUpdateDate(DateUtil.date());
        // 备件规格录入时，对首尾的空格进行自动去除，中间的空格最多只有两个
        String spec = sparePart.getSpec();
        if (StrUtil.isNotEmpty(spec)) {
            sparePart.setSpec(handleSpec(spec));
        }
        // 检查是否设置图片，如果没有则设置默认图片
        if (StrUtil.isEmpty(sparePart.getReserve2())) {
            sparePart.setReserve2(BaseConsts.SP_DEFAULT_IMAGE_URL);
        }
        return sparePartDao.update(sparePart);
    }

    @Override
    public int delete(String id) {
        return sparePartDao.delete(id);
    }

    @Override
    public int deleteBatch(String[] ids) {
        return sparePartDao.deleteBatch(ids);
    }

    @Override
    public List<SparePartEntity> getSpconsume(Query query) {
        return sparePartDao.getSpconsume(query);
    }

    @Override
    public int querySpconsumeTotal(Query query) {
        return sparePartDao.querySpconsumeTotal(query);
    }

    @Override
    public SparePartEntity queryByCode(String partCode) {
        return sparePartDao.queryByCode(partCode);
    }

    @Override
    public int importE(MultipartFile file) {
        // 获取工场Map
        List<FactoryTypeEntity> factoryTypeList = factoryTypeService.queryListByType(FactoryTypeEnum.SPARE_PART);
        Map<String, String> factoryTypeMap = MapUtil.newHashMap();
        for (FactoryTypeEntity factoryType : factoryTypeList) {
            factoryTypeMap.put(factoryType.getFaName(), factoryType.getId());
        }
        // 获取备件分类
        List<SparePartCategory> sparePartCategories = sparePartDao.listCategory();
        Map<String, List<SparePartCategory>> collect = sparePartCategories.stream().collect(Collectors.groupingBy(SparePartCategory::getName));

        List<String[]> list = ExcelImport.getExcelData(file);
        int count = 0;
        if (CollectionUtil.isNotEmpty(list)) {
            for (int i = 1; i < list.size(); i++) {
                String[] array = list.get(i);

                SparePartEntity sp = null;
                // 如果导入模板中含有备件编码，则查询并更新
                String spareCode = array[0];
                boolean isSave = false;
                if (StrUtil.isNotEmpty(spareCode)) {
                    sp = sparePartDao.queryByCode(spareCode);
                }
                if (sp == null) {
                    isSave = true;
                    sp = new SparePartEntity();
                    String id = RandomUtil.randomString(32);
                    sp.setId(id);
                    sp.setDelFlag(1);
                    sp.setCreateDate(new Date());
                    sp.setCreateUser(ShiroUtils.getUserId());
                    // 默认为未审批状态
                    sp.setStatus(0);
                    sp.setType(1);
                    sp.setStockNum(0);
                    sp.setScrapNum(0);
                    sp.setInitNum(0);
                    if (StrUtil.isEmpty(spareCode)) {
                        sp.setPartCode(generateUniqueCode());
                    } else {
                        sp.setPartCode(spareCode);
                    }
                }
                // 备件名称  1
                if (StrUtil.isNotEmpty(array[1])) {
                    sp.setName(array[1]);
                }
                // 备件规格 2
                if (StrUtil.isNotEmpty(array[2])) {
                    sp.setSpec(array[2]);
                }
                // 设置单位  3
                if (StrUtil.isNotEmpty(array[3])) {
                    sp.setUnit(array[3]);
                }
                // ERP编码 4
                if (StrUtil.isNotEmpty(array[4])) {
                    sp.setErpCode(array[4]);
                }
                // 备注 5
                if (StrUtil.isNotEmpty(array[5])) {
                    sp.setRemark(array[5]);
                }
                // 安全库存数 6
                if (StrUtil.isNotEmpty(array[6])) {
                    sp.setSafeNum(Integer.parseInt(array[6]));
                }
                // 初始数 7
                if (StrUtil.isNotEmpty(array[7])) {
                    sp.setInitNum(Integer.parseInt(array[7]));
                }
                // 设置供应厂家 8
                if (StrUtil.isNotEmpty(array[8])) {
                    sp.setProducor(array[8]);
                    // 如果包含，则进行调整修改
                    if (factoryTypeMap.containsKey(sp.getProducor())) {
                        sp.setSupplierId(factoryTypeMap.get(sp.getProducor()));
                    }
                }
                // 设置设备类型   9
                if (StrUtil.isNotEmpty(array[9])) {
                    sp.setDevType(array[9]);
                    DevTypeEntity devType = devTypeService.queryObjectByCode(array[9]);
                    if (devType != null) {
                        sp.setDevTypeName(devType.getTypeName());
                    }
                }
                // 专用还是通用 10
                if (StrUtil.isNotEmpty(array[10])) {
                    sp.setType(Integer.parseInt(array[10]));
                }
                // 一次装机量 11
                if (StrUtil.isNotEmpty(array[11])) {
                    sp.setReserve1(array[11]);
                }
                // 单价 12
                if (StrUtil.isNotEmpty(array[12])) {
                    String priceStr = array[12];
                    if (NumberUtil.isNumber(priceStr)) {
                        sp.setPrice(NumberUtil.toBigDecimal(priceStr));
                    } else {
                        sp.setPrice(NumberUtil.toBigDecimal("0.0"));
                    }
                }
                // 设置planAbc 13
                if (StrUtil.isNotEmpty(array[13])) {
                    sp.setPlanAbc(array[13]);
                }
                // 使用数量 14
                if (StrUtil.isNotEmpty(array[14])) {
                    sp.setUseNum(Integer.parseInt(array[14]));
                }
                // 是否是关键备件  15
                if (StrUtil.isNotEmpty(array[15])) {
                    sp.setIsKey("是".equals(array[15]) ? 1 : 0);
                }
                // 备件分类 16
                if (StrUtil.isNotEmpty(array[16])) {
                    List<SparePartCategory> matchedSparePartCategoryList = collect.get(array[16]);
                    if (CollectionUtil.isNotEmpty(matchedSparePartCategoryList)) {
                        sp.setInstallPosition(matchedSparePartCategoryList.get(0).getId());
                    } else {
                        sp.setInstallPosition(array[16]);
                    }
                }
                try {
                    count += isSave ? sparePartDao.save(sp) : sparePartDao.update(sp);

                } catch (Exception ex) {
                    System.out.println(spareCode);
                }
            }
        }
        return count;
    }

}
